/*
	This script file is part of the Sonic 3 A.I.R. script software distribution.
	Copyright (C) 2017-2024 by Eukaryot

	Published under the GNU GPLv3 open source software license, see license.txt
	or https://www.gnu.org/licenses/gpl-3.0.en.html
*/



//# address-hook(0x0273e4) end(0x02741e)
function void fn0273e4()
{
	objA0.hitbox_extends.y = 0x10
	objA0.mapping_offset = 0x226854
	objA0.sprite_attributes = (sprite_attribute.PALETTE.LINE2 | 0x02e6)
	objA0.box_size.x = 0x10
	objA0.box_size.y = 0x20
	u32[A0 + 0x3c] = 0x0276d8
	objA0.render_flags = render_flag.WORLD
	objA0.sprite_priority = 0x0200
	objA0.animation.sprite = 7

	objA0.update_address = 0x027424
	fn027424()
}


//# address-hook(0x027424) end(0x027590)
function void fn027424()
{
	u16[A0 + 0x30] = u16[0xffffb000 + 0x18]
	objA0.value32 = u16[0xffffb04a + 0x18]

	D1.u16 = 0x1b
	D2.u16 = 0x20
	D3.u16 = 0x21
	D4.u16 = objA0.position.x.u16
	fn01dc56()

	D0.u8 = objA0.flags2a & (object.flag.P1_PUSHING | object.flag.P2_PUSHING)
	if (D0.u8 == 0)
	{
		DrawOrUnloadObject()
		return
	}

	A1 = 0xffffb000
	D1.u16 = u16[A0 + 0x30]
	if (objA0.flags2a & object.flag.P1_PUSHING && objA1.state == char.state.ROLLING && abs(D1.s16) >= 0x0480)
	{
		if (objA0.flags2a & object.flag.P2_PUSHING)
		{
			objA0.flags2a &= ~object.flag.P2_PUSHING

			A2 = 0xffffb04a
			u8[A2 + 0x2a] &= ~char.flag.PUSHING
			if (u8[A2 + 0x20] == char.state.ROLLING)
			{
				u16[A2 + 0x18] = objA0.value32
				u16[A2 + 0x1c] = u16[A2 + 0x18]
			}
		}
	}
	else
	{
		A1 = 0xffffb04a
		D1.u16 = objA0.value32
		if ((objA0.flags2a & object.flag.P2_PUSHING) == 0 || u8[A1 + 0x20] != char.state.ROLLING || abs(D1.s16) < 0x0480)
		{
			DrawOrUnloadObject()
			return
		}

		if (objA0.flags2a & object.flag.P2_PUSHING)	// Isn't this always true here?
		{
			objA0.flags2a &= ~object.flag.P2_PUSHING
			u8[0xffffb04a + 0x2a] &= ~char.flag.PUSHING
		}
	}

	if (objA0.flags2a & object.flag.P1_PUSHING)
	{
		objA0.flags2a &= ~object.flag.P1_PUSHING
		u8[0xffffb000 + 0x2a] &= ~char.flag.PUSHING
	}
	objA1.velocity.x = D1.u16

	D0.u16 = objA0.position.x.u16
	if (D0.u16 >= objA1.position.x.u16)
	{
		A4 = 0x027718
		objA1.position.x.u16 -= 4
	}
	else
	{
		A4 = 0x0276d8
		objA1.position.x.u16 += 4
	}

	objA1.groundspeed = objA1.velocity.x
	D1.u8 = objA0.subtype2c
	if (objA0.subtype2c != 0)
	{
		bool createWaterStream = true

		if (objA0.subtype2c == 0x1f)
		{
			// Let the water rise (in Knuckles' area)
			global.level_flag02 = 1
			water.height.target = 0x0660
			if (super.active)
			{
				water.height.changerate = 2
			}
		}
		else
		{
			// Create the water flow logic (visual effect is separate)
			if (allocDynamicObjectAfterA0())
			{
				objA1.update_address = 0x0295c2
				objA1.position.x.u16 = objA0.position.x.u16
				objA1.position.y.u16 = objA0.position.y.u16 + 2
				u8[A1 + 0x24] = 0x07
				u8[A1 + 0x2c] = D1.u8
			}
			else
			{
				createWaterStream = false
			}
		}

		if (createWaterStream)
		{
			// Create water stream visual effect
			if (allocDynamicObjectAfterA0())
			{
				objA1.update_address = 0x029896
				objA1.position.x.u16 = objA0.position.x.u16
				objA1.position.y.u16 = objA0.position.y.u16 - 0x20
				objA1.velocity.y = 1
				u8[A1 + 0x2c] = D1.u8
			}
		}
	}

	objA0.update_address = 0x027592
	fn0275f2()
	fn027592()
}


//# address-hook(0x027592) end(0x0275ac)
function void fn027592()
{
	UpdateMovementStraightSimple()
	objA0.velocity.y += 0x18
	if (objA0.render_flags & render_flag.VISIBLE)
	{
		DrawObject()
	}
	else
	{
		UnloadObject()
	}
}


//# address-hook(0x0275b2) end(0x0275e0)
function void fn0275b2()
{
	D0 = 0
	objA0.animation.sprite = objA0.animation.frame
	++objA0.animation.frame
	if (objA0.animation.frame >= 6)
		objA0.animation.frame = 0

	UpdateMovementStraightSimple()
	objA0.velocity.y += 0x18
	if (!(objA0.render_flags & render_flag.VISIBLE))
	{
		UnloadObject()
	}
	else
	{
		DrawObject()
	}
}


//# address-hook(0x0275f2) end(0x0276d2)
function void fn0275f2()
{
	A5 = 0x0275e6
	D0 = objA0.animation.sprite * 2
	A3 = objA0.mapping_offset
	A2 = A3 + 0x1a
	A2 += u16[A3 + D0.u16]
	D4 = 0x0275b2
	D5.u8 = objA0.render_flags
	D1 = 0x0b

	while (D1.s16 >= 0)
	{
		if (!allocDynamicObjectAfterA0())
		{
			playSound(SFX_COLLAPSE)
			return
		}

		objA1.update_address = D4
		objA1.mapping_offset = A3
		objA1.render_flags = D5.u8
		objA1.sprite_attributes = objA0.sprite_attributes
		u8[A1 + 0x08] = u8[A0 + 0x08]
		objA1.box_size.x = objA0.box_size.x
		objA1.velocity.x = u16[(A4+=2)-2]
		objA1.velocity.y = u16[(A4+=2)-2]
		u8[A1 + 0x22] = u8[(A5+=1)-1]
		u8[A1 + 0x23] = u8[A1 + 0x22]

		D0.u16 = objA0.position.y.u16 + s8[A2]
		A2 += 4
		objA1.position.y.u16 = D0.u16
		D0.u16 = u16[(A2+=2)-2] + objA0.position.x.u16
		objA1.position.x.u16 = D0.u16
		--D1.s16
	}

	D0 = objA0.animation.sprite * 2
	A3 = objA0.mapping_offset + u16[A3 + D0.u16]
	D1.u16 = u16[(A3+=2)-2] - 1		// Only "A3 += 2" seems relevant here
	D1 = 3
	objA0.render_flags |= render_flag.STATIC_MAPPING
	D4 = objA0.update_address
	D5.u8 = objA0.render_flags
	A1 = A0

	while (true)
	{
		objA1.update_address = D4
		objA1.mapping_offset = A3
		objA1.render_flags = D5.u8
		objA1.position.x.u16 = objA0.position.x.u16
		objA1.position.y.u16 = objA0.position.y.u16
		objA1.sprite_attributes = objA0.sprite_attributes
		u8[A1 + 0x08] = u8[A0 + 0x08]
		objA1.box_size.x = objA0.box_size.x
		objA1.velocity.x = u16[(A4+=2)-2]
		objA1.velocity.y = u16[(A4+=2)-2]

		--D1.s16
		if (D1.s16 < 0)
			break

		if (!allocDynamicObjectAfterA0())
			break

		A3 += 6
	}

	playSound(SFX_COLLAPSE)
}



// Water flow effect

//# address-hook(0x0299f4) end(0x029a1e)
function void fn0299f4()
{
	if ((level.framecounter.low & 1) == 0)
	{
		objA0.render_flags ^= render_flag.FLIP_X
	}

	UpdateMovementSimple()
	if (!(objA0.render_flags & render_flag.VISIBLE) && objA0.velocity.y >= 0x0c00)
	{
		objA0.position.x.u16 = 0x7ff0
	}

	DrawOrUnloadObject()
}


//# address-hook(0x029abe) end(0x029af2)
function void fn029abe()
{
	--objA0.countdown_value
	if (objA0.countdown_value < 0)
	{
		objA0.countdown_value = 0x0b
		objA0.position.x.u16 = 0x7ff0
	}

	if ((level.framecounter.low & 1) == 0)
	{
		objA0.render_flags ^= render_flag.FLIP_X
	}

	UpdateMovementSimple()
	if (!(objA0.render_flags & render_flag.VISIBLE))
	{
		objA0.position.x.u16 = 0x7ff0
	}

	DrawOrUnloadObject()
}
